﻿//-----------------------------------------------------------------------
// <copyright file="ActionRepositoryTest.cs" company="FastNET Services">
//     Copyright (c) 2008-2009. All Rights Reserved.
// </copyright>
// <license>
//     GPLv2
// </license>
// <warranty>
//     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
//     BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </warranty>
//-----------------------------------------------------------------------
#region Usings

using System;
using System.Collections.Generic;
using System.Data.EntityClient;
using System.Linq;
using FastNET.CleanAct.Client.ManagerEngineData.Entities;
using FastNET.CleanAct.Client.ManagerEngineData.Repositories;
using FastNET.CleanAct.Common.Repository;
using FastNET.CleanAct.Common.Repository.Interfaces.DataInterfaces.ManagementEngine;
using FastNET.CleanAct.Testing.Client.ManagerEngineData.Helpers;
using FastNET.CleanAct.Testing.Mockup.DataLayer;
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace FastNET.CleanAct.Testing.Client.ManagerEngineData.Repositories
{
    /// <summary>
    /// This is a test class for ActionRepository and is intended
    /// to contain all ActionRepository Unit Tests
    /// </summary>
    [TestClass]
    public class ActionRepositoryTest
    {
        #region Fields

        private static EntityConnection _connection;
        private ActionRepository _repository;

        #endregion

        #region TestContext

        /// <summary>
        /// Gets or sets the test context which provides
        /// information about and functionality for the current test run.
        /// </summary>
        public TestContext TestContext { get; set; }

        #endregion

        #region Additional test attributes

        /// <summary>
        /// Run initialization for all unit tests for this class
        /// </summary>
        /// <param name="testContext">TestContext for this class during initialization</param>
        [ClassInitialize]
        public static void ClassInitialize(TestContext testContext)
        {
            _connection = DBHelper.CreateConnection();
            _connection.Open();
            DBHelper.ClearDatabase();
        }

        /// <summary>
        /// Run cleanup for all unit tests for this class
        /// </summary>
        [ClassCleanup]
        public static void ClassCleanup()
        {
            _connection.Close();
        }

        /// <summary>
        /// Run individual unit test preparation
        /// </summary>
        [TestInitialize]
        public void TestInitialize()
        {
            _repository = new ActionRepository(_connection);
        }

        /// <summary>
        /// Run individual unit test cleanup
        /// </summary>
        [TestCleanup]
        public void TestCleanup()
        {
            DBHelper.ClearDatabase();
        }

        #endregion

        #region Connection

        /// <summary>
        /// A test for Connection
        /// </summary>
        [TestMethod]
        public void Connection()
        {
            ActionRepository_Accessor target = new ActionRepository_Accessor(_connection);
            Assert.AreEqual(_connection, target.Connection);
        }

        #endregion

        #region Save

        /// <summary>
        /// A test for Save
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void Save_Null_ThrowsException()
        {
            _repository.Save(null);
        }

        /// <summary>
        /// A test for Save
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(InvalidCastException))]
        public void Save_InvalidData_ThrowsException()
        {
            _repository.Save(new MockAction());
        }

        /// <summary>
        /// A test for Save
        /// </summary>
        [TestMethod]
        public void Save_Success()
        {
            _repository.Save(ActionHelper.Create(TemplateHelper.CreateDB().ID));

            using (ManagerDataEntities dataSource = new ManagerDataEntities(_connection))
            {
                Assert.AreEqual(1, dataSource.Actions.Count());
            }
        }

        #endregion

        #region Retrieve

        #region NoParams

        /// <summary>
        /// A test for Retrieve
        /// </summary>
        [TestMethod]
        public void Retrieve_NoParams_3Items()
        {
            List<IActionData> createdItems = new List<IActionData>
                                                {
                                                    ActionHelper.CreateDB(),
                                                    ActionHelper.CreateDB(),
                                                    ActionHelper.CreateDB()
                                                };

            IEnumerable<IActionData> retrievedItems = _repository.Retrieve();

            Assert.IsNotNull(retrievedItems);
            Assert.AreEqual(createdItems.Count, retrievedItems.Count(), "Count Mismatch");

            foreach (IActionData retrievedItem in retrievedItems)
            {
                bool foundItem = false;

                foreach (IActionData createdItem in createdItems)
                {
                    if (retrievedItem.ID != createdItem.ID)
                    {
                        continue;
                    }

                    foundItem = true;
                    break;
                }

                if (!foundItem)
                {
                    Assert.Fail("Item not found in expected list");
                }
            }
        }

        /// <summary>
        /// A test for Retrieve
        /// </summary>
        [TestMethod]
        public void Retrieve_NoParams_0Items()
        {
            IEnumerable<IActionData> retrievedItems = _repository.Retrieve();

            Assert.IsNotNull(retrievedItems);
            Assert.AreEqual(0, retrievedItems.Count(), "Count Mismatch");
        }

        #endregion

        #region ByID

        /// <summary>
        /// A test for Retrieve
        /// </summary>
        [TestMethod]
        public void Retrieve_ByID_Success()
        {
            IActionData createdItem = ActionHelper.CreateDB();

            IActionData retrievedItem = _repository.Retrieve(createdItem.ID);

            Assert.AreEqual(createdItem.ID, retrievedItem.ID, "ID");
        }

        /// <summary>
        /// A test for Retrieve
        /// </summary>
        [TestMethod]
        public void Retrieve_ByID_NoneFound()
        {
            IActionData retrievedItem = _repository.Retrieve(new Identity(Guid.Empty));

            Assert.IsNull(retrievedItem, "Action Found");
        }

        /// <summary>
        /// A test for Retrieve
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(InvalidCastException))]
        public void Retrieve_ByID_InvalidIdentity()
        {
            _repository.Retrieve(new Identity(123));
        }

        #endregion

        #endregion

        #region Delete

        /// <summary>
        /// A test for Delete
        /// </summary>
        [TestMethod]
        public void Delete_Success()
        {
            IActionData createdItem = ActionHelper.CreateDB();

            _repository.Delete(createdItem);

            using (ManagerDataEntities dataSource = new ManagerDataEntities(_connection))
            {
                Assert.AreEqual(0, dataSource.Actions.Count(), "Items Found");
            }
        }

        /// <summary>
        /// A test for Delete
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void Delete_NullIAction()
        {
            _repository.Delete(null);
        }

        /// <summary>
        /// A test for Delete
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(InvalidCastException))]
        public void Delete_InvalidIAction()
        {
            _repository.Delete(new MockAction());
        }

        /// <summary>
        /// A test for Delete
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void Delete_AlreadyDeleted()
        {
            IActionData createdItem = ActionHelper.CreateDB();

            _repository.Delete(createdItem);

            // Try to redelete it
            _repository.Delete(createdItem);
        }

        /// <summary>
        /// A test for Delete
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void Delete_DeleteNewAction()
        {
            IActionData createdItem = ActionHelper.Create();

            _repository.Delete(createdItem);
        }

        #endregion

        #region Create

        /// <summary>
        /// A test for Create
        /// </summary>
        [TestMethod]
        public void Create()
        {
            IActionData item = _repository.Create();

            Assert.IsNotNull(item, "Item is null");
        }

        #endregion
    }
}
